import random

from django.shortcuts import render

import logging
# 1. 导入: 在需要使用的位置导入
# 2. 创建日志记录器: 导入后创建日志器才能使用
logger = logging.getLogger('django')

from django.views import View

# Create your views here.
from django_redis import get_redis_connection

from .libs.yuntongxun.ccp_sms import CCP


import re
import json
from django.views import View
from verifications.libs.captcha.captcha import captcha
from django.http import HttpResponse, JsonResponse


# 图片验证码接口
class ImageCodeView(View):

    def get(self, request):
        # 1.请求参数
        cur = request.GET.get('cur')
        pre = request.GET.get('pre')
        # 2,校验参数
        # 3.1 调用 captcha 第三方库 生成图片二维码
        text, image = captcha.generate_captcha()

        print('图片验证码:', text)

        # 3.2 把验证码写入 redis 数据库 (uuid 作为 redis数据库的key)
        # get_redis_connection函数:功能是 获取redis 连接对象,参数是一个字符串(是django缓存配置名称)
        # 返回值是一个 redis 的连接对象

        conn = get_redis_connection('verify_code')

        conn.setex('img_%s' % cur, 300, text)  # setex img_37728d6c-e219-44c5-8f81-4245a9e557a4 300 KJHG
        result = conn.get('img_%s' % pre)
        if result:
            conn.delete('img_%s'%pre)

        # 4.构建响应

        return HttpResponse(image,content_type='image/jpeg')

# 短信验证码接口
class SmsCodeView(View):
    def post(self, request):
        # 提取参数
        data = json.loads(request.body.decode())
        mobile = data.get('mobile')
        cur = data.get('id')
        image_code = data.get('text')
        # 校验参数
        if not all([mobile, image_code, cur]):
            return JsonResponse({'errno': 400, 'errmsg': '缺少必要参数'})
            # 格式检验
        if not re.match(r'^[a-zA-Z0-9]{4}$', image_code):
            return JsonResponse({
                'errno': 400,
                'errmsg': '图形验证码有误',
            })
        # if not re.match(r'^[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}$', cur):
        #     return JsonResponse({
        #         'errno': 400,
        #         'errmsg': 'text有误',
        #     })
        # 业务数据处理
        # 检验用户填写的图形验证码和redis中存储的验证码是否一致
        conn = get_redis_connection('verify_code')  # 2号库
        # conn.get()函数返回值是一个字节如：b'AHGF' 或者　None(图形验证码过期)
        image_code_id = conn.get('img_%s' % cur)
        print(image_code_id)
        # 为了避免图形验证码被重复使用，我们遵循一个原则：读一次删一次'
        try:
            conn.delete('img_%s' % cur)
        except Exception as e:
            logger.error(e)
        if not image_code_id:
            # 图形验证码过期
            return JsonResponse({
                'errno': 400,
                'errmsg': '图形验证码过期',
            })
        # 判断图形验证码是否正确，由于从redis里面获取的数据为二进制格式
        # 故先转化为字符串，并把用户输入的图形验证码和获取的图形验证码统一改为小写
        if image_code.lower() != image_code_id.decode().lower():
            return JsonResponse({
                'errno': 400,
                'errmsg': '输入的图形验证码错误',
            })
        # 业务数据处理
        # 发送短信前，需要判断标志存在不存在
        flag = conn.get('flag_%s' % mobile)
        if flag:
            # 如果flag存在，则表明60秒之内发送过短信，此时不允许再发送
            return JsonResponse({
                'errno': 400,
                'errmsg': '请勿重复发送,60秒后再尝试'
            })
        # 生成六位数的随机的随机验证码
        sms_code = '%06d' % random.randint(0, 999999)
        print('短信验证码：', sms_code)
        logger.info(sms_code)
        p = conn.pipeline()  # 获取管道对象

        # 保存短信验证码
        p.setex('sms_%s' % mobile, 300, sms_code)
        # 发送短信成功，记录标志信息为期60秒，表示60秒中之内发送过短信
        p.setex('flag_%s' % mobile, 60, -1)
        # 通过管道对象的execute函数调用之前搜集的指令一次性发送给redis批量执行
        p.execute()
        # 发送短信验证码信息
        ccp = CCP()
        # 由于测试账号只提供ｉｄ为１的短信模板
        # 5分钟提示有效期一定要和redis存储短信验证码有效期保持一致
        ccp.send_template_sms(mobile, [sms_code, 5], 1)
        # ccp_send_sms_code.delay(mobile, sms_code)
        # 构建响应
        return HttpResponse({
            'errno': 0,
            'errmsg': 'ok'
        })
